import { defineStore } from 'pinia';
import { orderBy, get, isEmpty, unionWith } from 'lodash-es';
import { handleCommonRes } from '../utils/resolver.js';
import { assign, getReplacedData, mergeValidData, parseJson, parseStr } from '../utils/index.js';
import { getStoreId } from './utils.js';
import vueGlobal from '../vueGlobal.js';

const id = getStoreId('staticDataStore');
export const useStaticDataStore = defineStore(id, {
  state: () => ({
    data: {},
  }),
  getters: {
    getReplacedData(state) {
      return (fields, option) => {
        const { fieldsMap, parseType, defaultValue } = assign(option, {
          fieldsMap: null,
          parseType: 'json',
          defaultValue: {},
        });
        if (!fields) {
          return defaultValue;
        }
        if (typeof fields === 'object') {
          return getReplacedData(state.data, fields);
        }
        if (typeof fields === 'string') {
          const parse = { json: parseJson, string: parseStr };
          const tempData = parse[parseType](get(state.data, fields), defaultValue);
          return typeof fieldsMap === 'object' && fieldsMap ? getReplacedData(tempData, fieldsMap) : tempData;
        }
      };
    },
    getMergedData(state) {
      return (dataSource, fields, option) => {
        const tempData = this.getReplacedData(fields, option);
        if (!tempData) {
          return dataSource;
        }
        return mergeValidData(dataSource, [tempData]);
      };
    },
    getMergedList(state) {
      return (dataSource, fields, option) => {
        let { format, keyField, valueField, uniqueKey, orderKey, order } = assign(option, {
          format: null,
          keyField: null,
          valueField: null,
          uniqueKey: 'name',
          orderKey: 'value',
          order: false, // 'asc', 'desc'
        });
        let list = dataSource;
        let tempList = this.getReplacedData(fields, assign(option, { defaultValue: [] }));
        if (typeof format === 'function') {
          tempList = format(tempList);
        }
        if (tempList && tempList.length) {
          if (keyField && valueField) {
            const data = tempList.reduce((res, item) => {
              return Object.assign(res, { [item[keyField]]: item[valueField] });
            }, {});
            list = unionWith(tempList, dataSource, (m, n) => {
              return m[uniqueKey] === n[uniqueKey];
            }).map((item) => {
              return mergeValidData(item, [{ [valueField]: data[item[keyField]] }]);
            });
          } else {
            const data = tempList.reduce((res, item) => {
              return Object.assign(res, { [item[uniqueKey]]: item });
            }, {});
            // 假数据列表与真实数据要合并，不然填写的假数据显示不出来
            list = unionWith(tempList, dataSource, (m, n) => {
              return m[uniqueKey] === n[uniqueKey];
            }).map((item) => {
              return mergeValidData(item, [data[item[uniqueKey]]]);
            });
          }
        }
        return order === null || order === false ? list : orderBy(list, orderKey, order);
      };
    },
  },
  actions: {
    clearStaticData() {
      this.$reset();
    },
    // 设置假数据
    setData(data) {
      if (typeof data === 'object') {
        this.data = Object.assign({}, this.data, data);
      }
    },
    async getStaticDataAsync(area_code) {
      if (!isEmpty(this.data)) {
        return;
      }
      const params = { area_code: area_code };
      const $axios = vueGlobal.get('$axios');
      const api = (params) => $axios.get('/xw-microservice/xw-api/v3/tempShow/list/open', { params });
      this.data = await handleCommonRes(api, params);
    },
  },
});
